package com.golte.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 */
public class HttpUtils {
    public static final String CONTENT_CHARSET_UTF_8 = "UTF-8";

    public static String sendGet(String url) {
        HttpGet get = null;
        CloseableHttpResponse resp = null;
        CloseableHttpClient client = null;
        try {
            client = HttpClients.createDefault();
            get = new HttpGet(url);
            resp = client.execute(get);
            int statusCode = resp.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                HttpEntity entity = resp.getEntity();
                String content = EntityUtils.toString(entity, "utf-8");
                return content;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (resp != null) {
                    resp.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (client != null) {
                    client.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static String get(String url, Map<String, String> params) throws IOException, URISyntaxException {
        return get(url, params, CONTENT_CHARSET_UTF_8, CONTENT_CHARSET_UTF_8);
    }

    public static String get(String url, Map<String, String> params, String requestCharset, String responseCharset) throws IOException, URISyntaxException {
        HttpClient client = buildHttpClient(false);
        HttpGet get = buildHttpGet(url, params, requestCharset);
        HttpResponse response = client.execute(get);
        if (!assertStatus(response)) {
            return null;
        }
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            return EntityUtils.toString(entity, StringUtils.isBlank(responseCharset) ? CONTENT_CHARSET_UTF_8 : responseCharset);
        }
        return null;
    }

    public static boolean assertStatus(HttpResponse res) throws IOException {
        boolean flag = false;
        switch (res.getStatusLine().getStatusCode()) {
            case HttpStatus.SC_OK:
                flag = true;
                break;
            default:
                flag = false;
        }
        return flag;
    }

    public static HttpGet buildHttpGet(String url, Map<String, String> params, String requestCharset)
            throws URISyntaxException {
        return new HttpGet(buildGetUrl(url, params, requestCharset == null ?
                CONTENT_CHARSET_UTF_8 : requestCharset));
    }

    private static String buildGetUrl(String url, Map<String, String> params, String requestCharset) {
        StringBuffer uriStr = new StringBuffer(url);
        if (params != null && params.size() > 0) {
            List<NameValuePair> ps = new ArrayList<>();
            for (String key : params.keySet()) {
                ps.add(new BasicNameValuePair(key, params.get(key)));
            }
            uriStr.append("?");
            uriStr.append(URLEncodedUtils.format(ps, requestCharset));
        }
        return uriStr.toString();
    }

    public static HttpClient buildHttpClient(boolean isMultiThread) {
        CloseableHttpClient client = null;
        if (isMultiThread) {
            client = HttpClientBuilder.create().setConnectionManager(
                    new PoolingHttpClientConnectionManager()).build();
        } else {
            client = HttpClientBuilder.create().build();
        }
        return client;
    }


    /**
     * post请求json
     *
     * @param url
     * @param json
     * @return
     * @throws Exception
     */
    public static String sendJsonPost(String url, String json) throws Exception {
        return sendPost(url, json, "application/json; charset=utf-8");
    }

    //    public static String sendJsonPost(String url, String content) {
    //        //        return sendPost(url, content, "application/json");
    //        return sendPost(url, content, "application/x-www-form-urlencoded");
    //    }

    public static String sendPost(String url, String content, String type) {
        CloseableHttpClient client = null;
        CloseableHttpResponse resp = null;
        try {
            System.out.println(content);
            client = HttpClients.createDefault();
            HttpPost post = new HttpPost(url);
            post.addHeader("Content-type", type);
            StringEntity entity = new StringEntity(content, ContentType.create(type, "UTF-8"));
            // StringEntity entity = new StringEntity(content);
            post.setEntity(entity);
            resp = client.execute(post);
            int statusCode = resp.getStatusLine().getStatusCode();
            if (statusCode >= 200 && statusCode < 300) {
                String str = EntityUtils.toString(resp.getEntity(), "utf-8");
                return str;
            }
        } catch (UnsupportedCharsetException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (client != null)
                    client.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            try {
                if (resp != null)
                    resp.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public static String postForm(String url, Map<String, String> params) throws IOException {
        return postForm(url, params, null);
    }

    public static String postForm(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        // set content type
        if (headers == null) {
            headers = new HashMap<String, String>();
        }

        /*if(null == headers.get("Content-Type") || "".equals(headers.get("Content-Type"))){
            headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        }*/

        // parse parameters
        String body = "";
        if (params != null) {
            boolean first = true;
            for (String param : params.keySet()) {
                if (first) {
                    first = false;
                } else {
                    body += "&";
                }
                String value = params.get(param);
                body += URLEncoder.encode(param, "UTF-8") + "=";
                body += URLEncoder.encode(value, "UTF-8");
            }
        }

        return post(url, body, headers);
    }

    public static String post(String url, String body, Map<String, String> headers) throws IOException {
        return fetch("POST", url, body, headers);
    }

    public static String fetch(String method, String url, String body, Map<String, String> headers) throws IOException {
        // connection
        URL u = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) u.openConnection();
        conn.setConnectTimeout(100000);
        conn.setReadTimeout(300000);

        // method
        if (method != null) {
            conn.setRequestMethod(method);
        }

        // headers
        if (headers != null) {
            for (String key : headers.keySet()) {
                conn.addRequestProperty(key, headers.get(key));
            }
        }

        // body
        if (body != null) {
            conn.setDoOutput(true);
            OutputStream os = conn.getOutputStream();
            os.write(body.getBytes());
            os.flush();
            os.close();
        }

        // response
        InputStream is = conn.getInputStream();
        String response = streamToString(is);
        is.close();

        // handle redirects
        if (conn.getResponseCode() == 301) {
            String location = conn.getHeaderField("Location");
            return fetch(method, location, body, headers);
        }

        return response;
    }

    public static String streamToString(InputStream in) throws IOException {
        StringBuffer out = new StringBuffer();

        BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        String line;
        while ((line = br.readLine()) != null) {
            out.append(line);
        }

        // byte[] b = new byte[4096];
        // for (int n; (n = in.read(b)) != -1; ) {
        //     out.append(new String(b, 0, n));
        // }

        return out.toString();
    }

    //过期时间
    public static int getExp(String exType) {
        int myDate;// 秒钟
        switch (exType) {
            case "1":
                myDate = 24 * 60 * 60 * 7;// 7天
                break;
            case "2":
                myDate = 24 * 60 * 60 * 14;// 14天
                break;
            case "3":
                myDate = 24 * 60 * 60 * 30;// 30天
                break;

            case "4":
                myDate = 10 * 60;// app测试使用  10分钟
                break;

            case "5":
                myDate = 24 * 60 * 60 * 30 * 12;// 一年
                break;

            case "6":
                myDate = 12 * 60 * 60;// 12小时 pc端使用的
                break;

            case "7":
                myDate = 1 * 60 * 60;// 1小时
                break;

            case "8":
                myDate = 6 * 60 * 60;// 6小时
                break;

            case "9":
                myDate = 24 * 60 * 60;// 24小时
                break;

            default:
                //myDate = COOKIE_EXPIRE_TIME;
                //关闭就过期
                myDate = 0;
        }
        return myDate;
    }
}
